#include <stdio.h>
#include "function.h"
#include <stdlib.h>
#include <unistd.h>	//sleep用
#include <string.h>	//strlen strcpy 用
#include <time.h>	//time用
#include "common.h"


void print_mem_info(const user_data usrNo);


//主界面
void main_menu() {
	system("clear");
	printf("                                ********************\n");
	printf("                                ***系统管理员模式***\n");
	printf("                                ********************\n");
	printf("                                     1.会员注册     \n");
	printf("                                     2.会员注销     \n");
	printf("                                   3.修改会员信息   \n");
	printf("                                   4.查看会员信息   \n");
	printf("                                     5.高级选项     \n");
	printf("                                  6.退出管理员模式  \n");
	printf("                                     0.退出系统     \n");
	printf("                                ********************\n");
	printf("                                ** 请输入指令 1-5 **\n");
	printf("                                ********************\n");

}


//用户注册
void resigner(){
	system("clear");
	user_data new_user;
	id_count++;	//ID计数+1

	printf("**********************\n");
	printf("******新会员注册******\n");
	printf("**********************\n");
	printf("*新会员注册* 请刷卡：");
	scanf("%s", new_user.cardNo);

	system("clear");
	printf("*新会员注册* 请输入姓名：");
	scanf("%s", new_user.name);
	system("clear");
	printf("*新会员注册* 请输入生日：");
	while(scanf("%d %d %d", &new_user.birth_year, &new_user.birth_month, &new_user.birth_day)<3){}
	system("clear");
	printf("*新会员注册* 请输入手机号：");
	while(1){
		scanf("%s", new_user.phone_num);
		if(strlen(new_user.phone_num)==11) break;
		system("clear");
		printf("手机号格式有误，请重新输入\n");
	}

	system("clear");
	printf("*新会员注册* 请输入会员类型（1.次卡 2.月卡 3.年卡）：");

	while(1){
	scanf("%d", &new_user.member_type);
	if(new_user.member_type >=1 && new_user.member_type<=3) break;
	system("clear");
	printf("*会员类型输入错误，请重新输入*\n");
	}

		
	struct tm* lc_time;
	long now_time = time(NULL);	//获取时间戳
	lc_time = localtime(&now_time);	//获取本地时间
	new_user.eff_time = new_user.resign_time = now_time;	//初始化失效日期和注册日期
	
	const long month_time = 30*86400; //30天的时间戳
	const long year_time = 365*86400; //365天的时间戳

	int time_count; //月卡、年卡增加计数

	switch(new_user.member_type){
		case 1:{
			       system("clear");
			       printf("正在办理次卡，请输入剩余次数：");
			       scanf("%d", &new_user.period);
		       }break;

		case 2:{
			       system("clear");
			       printf("正在办理月卡：请输入增加月份数量：");
			       scanf("%d", &time_count);
			       new_user.eff_time += time_count * month_time;

		       }break;

		case 3:{
			       system("clear");
			       printf("正在办理年卡，请输入增加年份数量：");
			       scanf("%d", &time_count);
			       new_user.eff_time += time_count * year_time;
		       }break;

	}


	new_user.userID = id_count; //计算用户ID
	new_user.isUsed = 1;	 //设置用户可用
	new_user.isLoged = 0;	//设置用户登录状态

	struct tm* ef_time;
	ef_time = localtime(&new_user.eff_time);	//计算过期时间

	system("clear");
	printf("\n*注册成功！您的ID为 %d*\n", id_count);
	prsanykey();

	FILE* fp = fopen("./users.dat", "ab");
	if(fp == NULL){
		printf("fopen faild\n");
	}

	fwrite(&new_user, sizeof(new_user), 1, fp); //写入用户信息
	
	fclose(fp);

	FILE* fp2 = fopen("./usrcnt", "rb+");
	if(fp2 == NULL){
		printf("fopen faild");
	}
	fwrite(&id_count, sizeof(id_count), 1, fp2); //id计数
	fclose(fp2);
	
	
	return;

}


//用户注销
void logoff(){

	char noToPrs[20]; //待删除用户的卡号
	int read_result = 0;  //查找结果 0否 1是
	char selres;	//是否删除结果 0否 1是
	user_data delUser; //创建待删除用户
	long found_pos = 0; //记录文件位置

	system("clear");
	printf("*会员注销* 请刷卡：");
	scanf("%s",noToPrs);
	//getchar();

	FILE* fp = fopen("./users.dat", "rb+");
	if(fp == NULL){
		printf("抱歉，数据文件打开失败\n");
		sleep(3);
		return;
	}

	while(fread(&delUser, sizeof(delUser), 1, fp) == 1){
		if(strcmp(delUser.cardNo, noToPrs) == 0){ //查询到卡号后修改判定结果
			read_result = 1;
			found_pos = ftell(fp) - sizeof(user_data); //标记当前位置
			break;
		}
	}
	system("clear");

	//以下两行测试用
	//printf("%s %s\n", delUser.cardNo, noToPrs);
	//printf("%d %d", read_result, delUser.isUsed);

	if(read_result == 1 && delUser.isUsed == 1){
		printf("要删除的用户信息如下：\n");
		print_mem_info(delUser);
		printf("是否删除该用户？(Y/N)");
		getchar();
		while(1){
			scanf("%c", &selres);
			if(selres == 'Y' || selres == 'y'){
				delUser.isUsed = 0;	
				fseek(fp, found_pos, SEEK_SET); //回退到记录位置
				fwrite(&delUser, sizeof(user_data), 1, fp);
				printf("删除成功！\n");
				break;
			}
			else if(selres == 'N' || selres == 'n'){
				break;
			}
		}
	}

	else{
		printf("抱歉，未找到该用户\n");

		fclose(fp);

		prsanykey();

		return;
	}
}


//打印用户信息
void print_mem_info(const user_data usrNo){
	printf("用户卡号：%s\n", usrNo.cardNo);	
	printf("用户ID：%d\n", usrNo.userID);
	printf("用户姓名：%s\n", usrNo.name);
	printf("手机号：%s\n", usrNo.phone_num);
	printf("生日：%d 年 %d 月 %d 日\n", usrNo.birth_year, usrNo.birth_month, usrNo.birth_day);
	printf("会员类型：");

	switch(usrNo.member_type){
		case 1:printf("次卡\n");break;
		case 2:printf("月卡\n");break;
		case 3:printf("年卡\n");break;
		case 4:printf("管理员\n");break;
		default:printf("未知\n");break;
	}

	if(usrNo.member_type == 1){
		printf("剩余次数：%d\n", usrNo.period);
	}

	struct tm* local_time = localtime(&usrNo.eff_time);
	if(usrNo.member_type == 2 || usrNo.member_type == 3){
		printf("到期日期：%04d %02d %02d\n", local_time->tm_year + 1900, local_time->tm_mon+1, local_time->tm_mday);
	}

}


void change() {
	char noToPrs[20];
	int idToPrs;
	long found_pos = -1;
	user_data userChg;
	int choice;
	int addnum;
	char yorn;
	char date_str[30];

	// 记录用户新信息
	char new_phone[15];
	char new_name[30];
	int new_year, new_month, new_day;

	const long month_time = 30 * 86400;
	const long year_time = 365 * 86400;

	system("clear");
	printf("*信息修改*请输入用户卡号：");
	scanf("%s", noToPrs);

	system("clear");
	printf("*信息修改*请输入用户ID：");
	scanf("%d", &idToPrs);

	FILE* fp = fopen("./users.dat", "r+");
	if (fp == NULL) {
		perror("fopen failed\n");
		return;
	}

	// 查找用户
	while (fread(&userChg, sizeof(user_data), 1, fp) == 1) {
		if (strcmp(userChg.cardNo, noToPrs) == 0 && 
				userChg.userID == idToPrs && 
				userChg.isUsed == 1) {
			found_pos = ftell(fp) - sizeof(user_data);
			break;
		}
	}

	if (found_pos == -1) {
		system("clear");
		printf("抱歉，未找到该用户\n");
		fclose(fp);
		prsanykey();
		return;
	}

	fseek(fp, found_pos, SEEK_SET);

	// 显示用户信息并选择修改项
	system("clear");
	printf("以下是该用户的信息：\n");
	print_mem_info(userChg);

	printf("请选择需要修改的内容：\n");
	printf("1.用户姓名\n");
	printf("2.手机号\n");
	printf("3.生日\n");

	if (userChg.member_type == 1) {
		printf("4.增加剩余次数\n");
	} else if (userChg.member_type == 2 || userChg.member_type == 3) {
		printf("4.续费日期\n");
	}

	printf("5.用户类型\n");
	printf(">: ");

	scanf("%d", &choice);

	int confirm_change(const char* prompt) {
		printf("%s，确认吗（Y/N）？", prompt);
		getchar();
		scanf("%c", &yorn);
		return (yorn == 'Y' || yorn == 'y');
	}

	switch (choice) {
		case 1: // 修改姓名
			system("clear");
			printf("请输入要修改的姓名：");
			scanf("%s", new_name);

			if (confirm_change(new_name)) {
				strcpy(userChg.name, new_name);
				printf("修改成功！\n");
			} else {
				printf("取消修改\n");
			}
			break;

		case 2: // 修改手机号
			system("clear");
			printf("请输入要修改的手机号：");
			scanf("%s", new_phone);

			if (confirm_change(new_phone)) {
				strcpy(userChg.phone_num, new_phone);
				printf("修改成功！\n");
			} else {
				printf("取消修改\n");
			}
			break;

		case 3: // 修改生日
			system("clear");
			printf("请输入要修改的生日（年 月 日）：");
			while (scanf("%d %d %d", &new_year, &new_month, &new_day) < 3) {}
			sprintf(date_str, "%04d-%02d-%02d", new_year, new_month, new_day);

			if (confirm_change(date_str)) {
				userChg.birth_year = new_year;
				userChg.birth_month = new_month;
				userChg.birth_day = new_day;
				printf("修改成功！\n");
			} else {
				printf("取消修改\n");
			}
			break;

		case 4: // 增加次数或续费
			system("clear");
			if (userChg.member_type == 1) {
				printf("请输入需要增加的次数：");
				scanf("%d", &addnum);

				if (confirm_change("增加次数")) {
					userChg.period += addnum;
					printf("修改成功！\n");
				}
			} 
			else if (userChg.member_type == 2) {
				printf("请输入需要增加的月份：");
				scanf("%d", &addnum);

				if (confirm_change("增加月份")) {
					userChg.eff_time += addnum * month_time;
					printf("修改成功！\n");
				}
			} 
			else if (userChg.member_type == 3) {
				printf("请输入需要增加的年份：");
				scanf("%d", &addnum);

				if (confirm_change("增加年份")) {
					userChg.eff_time += addnum * year_time;
					printf("修改成功！\n");
				}
			}

			else{
				prsanykey();
				return;
			}
			break;

		case 5: // 修改用户类型
			system("clear");
			printf("请输入目标用户要修改成的用户类型：\n");
			printf("1.次卡\n2.月卡\n3.年卡\n4.管理员\n>: ");
			scanf("%d", &addnum);

			if (addnum < 1 || addnum > 4) {
				printf("输入无效！请输入 1~4 的数字。\n");
				break;
			}

			if (userChg.member_type == addnum) {
				printf("修改失败！类型相同\n");
				break;
			}

			if (passwd()) {
				userChg.member_type = addnum;
				printf("修改成功！\n");
			}
			else {
				printf("修改失败！权限不足\n");
				prsanykey();
			}
			break;

		default:
			system("clear");
			printf("指令输入错误\n");
			prsanykey();
			fclose(fp);
			return;
	}

	// 保存修改
	fwrite(&userChg, sizeof(user_data), 1, fp);
	fclose(fp);

	prsanykey();
	system("clear");
}




//搜索用户信息
void search(){
	user_data search;
	char nums[20];
	int id;
	int isfound = 0;

	system("clear");
	printf("请输入需要搜索的用户的卡号：");
	scanf("%s", nums);
	system("clear");
	printf("请输入需要搜索的用户的ID：");
	scanf("%d", &id);
	FILE* fp = fopen("./users.dat", "r");

	while(fread(&search, sizeof(user_data), 1, fp) == 1){
		if(strcmp(search.cardNo, nums) == 0 && id == search.userID && search.isUsed == 1){
			isfound = 1;
			system("clear");
			printf("以下是该用户的信息：\n");
			print_mem_info(search);
			prsanykey();


			break;
		}

	}

	if(!isfound){
		system("clear");
		printf("抱歉，无法找到该用户\n");
		printf("即将跳转回主页面...\n");
		sleep(1);

	}


	fclose(fp);

}

void logquit() {
	while(1){
		char no[20];
		system("clear");
		getchar();
		printf("*用户您好！请刷卡：");
		scanf("%s", no);

		user_data user;
		int user_found = 0;
		long found_pos = -1;
		FILE* fp = fopen("./users.dat", "r+");
		FILE* fp2 = fopen("log.dat", "ab");

		if (fp == NULL) {
			perror("fopen failed\n");
			return;
		}

		while (fread(&user, sizeof(user_data), 1, fp) == 1) {
			if (strcmp(no, user.cardNo) == 0 && user.isUsed == 1) {
				user_found = 1;
				found_pos = ftell(fp) - sizeof(user_data);
				break;
			}
		}

		if (!user_found) {
			system("clear");
			printf("未找到用户，请联系管理员！\n");
			fclose(fp);
			prsanykey();
			return;
		}

		fseek(fp, found_pos, SEEK_SET);
		fread(&user, sizeof(user_data), 1, fp);
		fseek(fp, found_pos, SEEK_SET);

		time_t now_time = time(NULL);

		log curlog;

		system("clear");
		if (user.isLoged) {
			user.isLoged = 0;
			printf("用户 %s，谢谢使用，欢迎下次再来！\n", user.name);

			//记录用户登出日志
			curlog.type = 0;
			curlog.uid = user.userID;
			curlog.logtime = time(NULL);
			fwrite(&curlog, sizeof(log), 1, fp2);

			//user.lastexit = now_time;
			fwrite(&user, sizeof(user_data), 1, fp);
		}
		else {
			int can_login = 1;
			//user.lastin = now_time;

			//进入管理员模式
			if(user.member_type == 4){
				main_menu();
				admin_tab();
				fclose(fp);
				fclose(fp2);
				return;
			}

			if (user.member_type == 1 && user.period <= 0) {
				printf("您的用户类型为次卡，剩余使用次数不足\n");
				can_login = 0;
			}
			else if (user.member_type == 2 && user.eff_time < now_time) {
				printf("您的用户类型为月卡，已过期\n");
				can_login = 0;
			}
			else if (user.member_type == 3 && user.eff_time < now_time) {
				printf("您的用户类型为年卡，已过期\n");
				can_login = 0;
			}

			if (can_login) {
				user.isLoged = 1;
				printf("用户 %s ，欢迎！\n", user.name);

				//记录用户登入日志
				curlog.type = 1;
				curlog.uid = user.userID;
				curlog.logtime = time(NULL);
				fwrite(&curlog, sizeof(log), 1, fp2);

				if (user.member_type == 1) {
					user.period--;
					printf("您的用户类型为次卡，剩余次数：%d\n", user.period);
				}
				fwrite(&user, sizeof(user_data), 1, fp);
			} else {
				printf("登录失败");
				sleep(2);
			}
		}


		fclose(fp);
		fclose(fp2);
		sleep(2);
	}
}

void admin(){
	int choice;
	char newpwd[25];
	system("clear");
	user_data user;


	system("clear");
	printf("请输入要执行的操作：\n1.修改管理员密码\n2.查看统计分析\n3.查看登录日志\n");
	printf(">:");

	while(scanf("%d", &choice)){
		system("clear");
		if(choice == 1){
			printf("请输入新的管理员密码：");
			scanf("%s", newpwd);

			FILE* fp = fopen("./usrcnt", "r+");
			if (fp == NULL) {
				printf("无法打开文件！\n");
				break;
			}

			// 读取原来的ID计数
			int id_count;
			fread(&id_count, sizeof(int), 1, fp);

			// 关闭文件后重新以截断模式打开
			fclose(fp);

			// 重新打开文件，只保留ID计数部分
			fp = fopen("./usrcnt", "w+");
			if (fp == NULL) {
				printf("无法重新打开文件！\n");
				break;
			}

			// 先写入原来的ID计数
			fwrite(&id_count, sizeof(int), 1, fp);

			// 再写入新密码
			fwrite(newpwd, strlen(newpwd), 1, fp);

			printf("管理员密码修改成功！\n");
			fclose(fp);
			break;
		}
		if(choice == 2){
			system("clear");	
			statistics();
			break;
		}
		if(choice == 3){
			system("clear");
			systemlog();
			break;
		}

		else
			printf("输入错误，请重新输入！\n");


	}
}	

void statistics(){
	system("clear");
	user_data user;
	FILE* fp = fopen("./users.dat", "rb");
	if(fp == NULL){
		perror("fopen failed\n");
	}

	fseek(fp, 0, SEEK_SET);	//定位到文件开头

	int users = 0, t1cnt = 0, t2cnt = 0, t3cnt = 0;	//用户类型计数
	while(fread(&user, sizeof(user_data), 1, fp)){

		if(user.member_type == 1){
			t1cnt++;
			users++;
		}
		if(user.member_type == 2){
			t2cnt++;
			users++;
		}
		if(user.member_type == 3){
			t3cnt++;
			users++;
		}
		

		if(feof(fp)){
			break;
		}
		
	}
			


	printf("***统计数据***\n");
	printf("总用户数量：%d\n", users);
	printf("次卡用户数量：%d\n", t1cnt);
	printf("月卡用户数量：%d\n", t2cnt);
	printf("年卡用户数量：%d\n", t3cnt);
	prsanykey();
	fclose(fp);
	
}

void systemlog(){
	system("clear");
	log curlog;
	FILE* fp = fopen("./log.dat", "rb");
	if(fp == NULL){
		perror("fopen failed\n");
	}

	while(fread(&curlog, sizeof(log), 1, fp)){
		struct tm* lctime = localtime(&curlog.logtime);

		printf("用户ID : %d 于%4d年%2d月,%2d日", curlog.uid, lctime->tm_year + 1900, lctime->tm_mon + 1, lctime->tm_mday);

		if(curlog.type)
			printf("登出\n");
		else
			printf("登录\n");

		if(feof(fp))
			break;
	}
	prsanykey();
	fclose(fp);

}

void admin_tab(){
	int comm;

	while(1){
		printf(">>");
		if(scanf("%d", &comm) != 1){
			while(getchar() != '\n');
			comm = -1;
			continue;
		}

		switch(comm){
			case 1:{
				       resigner();
				       main_menu();
			       }break;

			case 2:{
				       logoff();
				       main_menu();

			       }break;

			case 3:{
				       change();
				       main_menu();
			       }break;

			case 4:{
				       search();
				       main_menu();
			       }break;

			case 5:{
				       admin();
				       main_menu();
			       }break;

			case 6:{
				       logquit();
				       main_menu();
			       }break;
			case 0:
			       {
				       system("clear");
				       printf("*****谢谢使用*****\n");
				       exit(0);
			       }break;

			default:{
					printf("***输入错误，请重新输入***\n");
				}break;
		}
	}



}
